package com.dattplace.controller;


import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.dattplace.cache.CacheFacade;
import com.dattplace.commons.Constants;
import com.dattplace.model.ResultCode;
import com.dattplace.model.ResultData;
import com.dattplace.model.User;
import com.dattplace.service.IUserService;
import com.dattplace.service.ImopService;
import com.dattplace.util.DESEncryption;
import com.dattplace.util.MD5Util;
import com.dattplace.util.PropertiesUtil;
import com.dattplace.util.RandomUtil;
import com.dattplace.util.StringUtil;
import com.dattplace.vo.UserVo;

import net.sf.json.JSONObject;


@Controller
@Path("/login")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public class LoginController {

    private final static CacheFacade cacheFacade = CacheFacade.getInstance();

	private static final Logger logger = Logger.getLogger(LoginController.class);
	@Autowired
	private Mapper mapper;

	@Autowired
	private IUserService userService;
	
	@Autowired
	private ImopService mopservice;

	private static final PropertiesUtil propertiesUtil = new PropertiesUtil("config.properties");

	@POST
	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
	@Path("/adminLogin")
	public UserVo adminLogin(@FormParam("userName") final String userName, @FormParam("password") final String password,
			@Context final HttpServletRequest request) {
		// 后台管理登陆时必须输入验证码
		final HttpSession session = request.getSession();
		String accessToken = MD5Util.string2MD5(userName + new Date().getTime());
		session.setMaxInactiveInterval(604800);// 设置session过期时间为1个小时，这里的以秒为单位的。
		Date lastLoginTime = new Date();
		
		User user = userService.queryUserByName(userName);
		
		/*User u =new User();
		u.setUserId(new RandomUtil().getRandomId());
		u.setUserName("admin");
		u.setPassword("4d31d5cec93bfcc47f103f0c1bc8a1a9");
		u.setUserType(1);
		List<User> uL =new ArrayList<>();
		uL.add(u);
		userService.saveUsers(uL);*/
		if (user == null) {
			return buildError(userName, 1, "用户不存在,请核对后输入");
		}
		
		if(user.getUserType()<1){
			return buildError(userName, 1, "该用户没有后台管理权限");
		}
		
		if(user.getAccountStatus()==1){
			return buildError(userName, 1, "用户已经停用");
		}
		String psw = generalPassword(userName, password);
		if (!psw.equals(user.getPassword())) {
			logger.info("Wrong password, " + userName + " login error.");
			return buildError(userName, 3, "用户名或者密码错误");
		}
		UserVo vo = mapper.map(user, UserVo.class);
		vo.setLastLoginTime(lastLoginTime);
		vo.setAuthenticated(true);
		vo.setAccessToken(accessToken);
		vo.setMenus(userService.getUserMeuns(user));
		// 记录登陆信息
		//userService.updateUserLoginInfo(accessToken,lastLoginTime,vo.getUserId());
		
		user =mapper.map(vo, User.class);
        session.setAttribute("showtimes_login", user);
		return vo;

	}
	
	/**
	 * 手机登录showtimes
	 * @param userName
	 * @param password
	 * @param request
	 * @return
	 */
	@POST
	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
	public ResultData<Object>  login( final UserVo userVo,@Context final HttpServletRequest request) {
		final HttpSession session = request.getSession();
		String accessToken = MD5Util.string2MD5(userVo.getUserName() + new Date().getTime());
		session.setMaxInactiveInterval(7776000*24*7);// 设置session过期时间为1个小时，这里的以秒为单位的。
		Date lastLoginTime = new Date();
		User user = userService.queryUserByName(userVo.getUserName());
		ResultData<Object> result =new ResultData<>();
		String userId =new RandomUtil().getRandomId();
		long expireTime =7776000;
		// 验证验证码
		String response = mopservice.verify(propertiesUtil.getProperty("mobappkey"), userVo.getUserName(),userVo.getZone(), userVo.getCheckCode());
		JSONObject obj =JSONObject.fromObject(response);
		int status = obj.getInt("status");
		if(status!=200){
			result.setResCode(ResultCode.FAILTURE_ERROR_CODE);
			result.setMsg("验证码不正确");
			return result;
		}
		if (user == null) {
			// 调用注册，写入用户信息
			user = new User();
			user.setUserName(userVo.getUserName());
			user.setUserId(userId);
			user.setMobile(userVo.getUserName());
			user.setCreateDate(new Date());
			user.setTokenTime(lastLoginTime);
			user.setLastLoginTime(lastLoginTime);
			user.setAccessToken(accessToken);
			user.setExpireTime(expireTime);
			user.setOnline(true);
			userService.register(user);
		} else {
			// 判断是否停用
			if(user.getAccountStatus()==1){
				result.setResCode(ResultCode.FAILTURE);
				result.setMsg("该用户已经停用");
				return result;
			}
			
			UserVo vo = mapper.map(user, UserVo.class);
			vo.setLastLoginTime(lastLoginTime);
			vo.setAuthenticated(true);
			vo.setAccessToken(accessToken);
			vo.setOnline(true);
			// 记录登陆信息
			userService.updateUserLoginInfo(accessToken, lastLoginTime,expireTime, vo.getUserId());
			user = mapper.map(vo, User.class);
		}
		// redis 记录登录信息
		Object redisObj =cacheFacade.get("showtimes_login", user.getUserId());
		if(redisObj!=null){
			cacheFacade.delete("showtimes_login", user.getUserId());
		}
        cacheFacade.putRList("showtimes_login", user.getUserId(), user);
        session.setAttribute("showtimes_login", user);
        result.setResCode(ResultCode.SUCCESS);
        result.setObj(user);
		return result;
	}
	

	/**
	 * 设置错误信息
	 * 
	 * @param userName
	 * @param errorCode
	 * @param errorMessage
	 * 
	 * @return
	 */
	private UserVo buildError(final String userName, final int errorCode, final String errorMessage) {

		final UserVo result = new UserVo();
		result.setAuthenticated(false);
		result.setErrorMessage(errorMessage);
		result.setErrorCode(errorCode);
		return result;
	}

	/**
	 * @param userName
	 * @param password
	 * @return
	 */
	private String generalPassword(final String userName, final String password) {
		String decryptStr = "";
		try {
			decryptStr = DESEncryption.decrypt(password, userName);
		} catch (IOException e) {
			logger.error("Error in decrypt. Reason: " + e.getMessage());
		} catch (Exception e) {
			logger.error("Error in decrypt. Reason: " + e.getMessage());
		}

		if (userName.indexOf("@") != -1) {
			String shortUserName = userName.substring(0, userName.indexOf("@"));
			return MD5Util.string2MD5(shortUserName.toLowerCase() + Constants.USER_KEY + MD5Util.string2MD5(decryptStr));
		} else {
			return MD5Util.string2MD5(userName.toLowerCase() + Constants.USER_KEY + MD5Util.string2MD5(decryptStr));
		}
	}
	
	
	public static void main(String[] args) {
		System.out.println(MD5Util.string2MD5("admin" + Constants.USER_KEY + MD5Util.string2MD5("showtimes@!~")));
	
		//4d31d5cec93bfcc47f103f0c1bc8a1a9
	}
	
	/**
	 * 退出登录
	 * @param request
	 * @return
	 */
	@GET
    @Path("/logout")
    public ResultData<Object> logout(@Context final HttpServletRequest request) {

		ResultData<Object> result =new ResultData<>();

        final HttpSession session = request.getSession();
        final User user = (User) session.getAttribute("showtimes_login");
        String userIosToken = null;
        String userId = null;
        if (user != null) {
            userId = user.getUserId();
        }
        logger.info("session user: " + user + "/" + userIosToken);

        userService.cleanUserLoginInfo(userId);
        session.setAttribute("showtimes_login", null);
        
        //删除redis 信息
        if(!StringUtil.isEmptyString(userId)){
        	cacheFacade.delete("showtimes_login", userId);
        }
        session.invalidate();
        result.setResCode(ResultCode.SUCCESS);
		return result;
    }
	
	
	@GET
    @Path("/adminlogout")
    public ResultData<Object> adminlogout(@Context final HttpServletRequest request) {

		ResultData<Object> result =new ResultData<>();

        final HttpSession session = request.getSession();
        final User user = (User) session.getAttribute("showtimes_login");
        session.setAttribute("showtimes_login", null);
        //删除redis 信息
        session.invalidate();
        result.setResCode(ResultCode.SUCCESS);
		return result;
    }

}
